package vsvm.gui.forms;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import vsvm.classifier.AbstractClassifier;
import vsvm.classifier.TestingParameters;
import vsvm.data.model.AbstractDataModel;
import vsvm.gui.Environment;
import java.awt.Insets;
import java.awt.FlowLayout;
import javax.swing.JProgressBar;

public class TrainClassifierForm extends JDialog{

	private static final long serialVersionUID = 100L;
	private JPanel jContentPane = null;
	private JPanel pnlCenter = null;
	private JPanel pnlLeft = null;
	private JPanel pnlTestData = null;
	private JComboBox cmbDataModel = null;	
	private AbstractClassifier classifier;	
	private TrainClassifierForm me = null;
	private TestingParameters tp = null;  //  @jve:decl-index=0:
	private boolean threadBusy = false;
	
	
	private void loadDataModels() {
		ArrayList<AbstractDataModel> m = Environment.getEnvironment().getWorkspace().getDataModels();
		cmbDataModel.setModel(new DefaultComboBoxModel(m.toArray()));
	}
	
	public void setDataModel(AbstractDataModel dm) {
		cmbDataModel.setSelectedItem(dm);
	}
		
	/**
	 * This method initializes pnlCenter	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getPnlCenter() {
		if (pnlCenter == null) {
			pnlCenter = new JPanel();
			pnlCenter.setLayout(new BorderLayout());
			pnlCenter.add(getPnlLeft(), BorderLayout.CENTER);
		}
		return pnlCenter;
	}

	/**
	 * This method initializes pnlLeft	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getPnlLeft() {
		if (pnlLeft == null) {
			pnlLeft = new JPanel();
			pnlLeft.setLayout(new BorderLayout());
			pnlLeft.setPreferredSize(new java.awt.Dimension(260,260));
			pnlLeft.add(getJPanel(), BorderLayout.SOUTH);
			pnlLeft.add(getPnlTestData(), BorderLayout.CENTER);
		}
		return pnlLeft;
	}

	/**
	 * This method initializes pnlTestData	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getPnlTestData() {
		if (pnlTestData == null) {
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 1;
			gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints.insets = new Insets(20, 100, 0, 0);
			gridBagConstraints.gridy = 3;
			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
			gridBagConstraints13.gridx = 0;
			gridBagConstraints13.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints13.gridy = 1;
			jLabel = new JLabel();
			jLabel.setText("Data model");
			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
			gridBagConstraints12.fill = GridBagConstraints.BOTH;
			gridBagConstraints12.gridy = 1;
			gridBagConstraints12.weightx = 1.0;
			gridBagConstraints12.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints12.gridx = 1;
			pnlTestData = new JPanel();
			pnlTestData.setLayout(new GridBagLayout());
			pnlTestData.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Training", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
			pnlTestData.add(getCmbDataModel(), gridBagConstraints12);
			pnlTestData.add(jLabel, gridBagConstraints13);
			pnlTestData.add(getJProgressBar(), gridBagConstraints);
		}
		return pnlTestData;
	}

	/**
	 * This method initializes cmbDataModel	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getCmbDataModel() {
		if (cmbDataModel == null) {
			cmbDataModel = new JComboBox();
			cmbDataModel.setPreferredSize(new java.awt.Dimension(220,25));
		}
		return cmbDataModel;
	}

	/**
	 * This method initializes btnTrain	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getBtnTrain() {
		if (btnTrain == null) {
			btnTrain = new JButton();
			btnTrain.setText("Train");
			btnTrain.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) 
				{
					if(threadBusy)
					{
						JOptionPane.showMessageDialog(me, "Training! " +
								"Press Cancel to stop.", "Thread is busy!", 0);
						return;
					}
					threadTrain = new ThreadTrain();
					threadTrain.start();
				}
			});
		}
		return btnTrain;
	}

	/**
	 * This is the default constructor
	 */
	public TrainClassifierForm(Component parent, AbstractClassifier cls) {
		super();
		me = this;
		
		initialize();
		
		setLocationRelativeTo(parent);
		classifier = cls;
		
		loadDataModels();
		
	}
	
	private JLabel jLabel = null;
	private JButton btnTrain = null;
	private JButton jButton = null;
	private JPanel jPanel = null;
	public void setNoTest() {
		pnlTestData.setEnabled(false);	
	}
	
	public TestingParameters getParameters() {
		return tp;		
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(322, 177);
		this.setResizable(false);
		this.setModal(true);
		this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		this.setTitle("Train data model");
		this.setContentPane(getJContentPane());
		this.addWindowListener(new java.awt.event.WindowAdapter() {
			@SuppressWarnings("deprecation")
			public void windowClosing(java.awt.event.WindowEvent e) {
				if(threadBusy &&  threadTrain != null){
					threadTrain.stop();
				}				
			}
		});
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getPnlCenter(), java.awt.BorderLayout.CENTER);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButton() {
		if (jButton == null) {
			jButton = new JButton();
			jButton.setText("Cancel");
			jButton.addActionListener(new java.awt.event.ActionListener() {
				@SuppressWarnings("deprecation")
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(threadBusy && threadTrain != null)
					{
						threadTrain.stop();
					}					
					me.dispose();
				}
			});
		}
		return jButton;
	}

	/**
	 * This method initializes jPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			FlowLayout flowLayout = new FlowLayout();
			flowLayout.setHgap(30);
			jPanel = new JPanel();
			jPanel.setLayout(flowLayout);
			jPanel.add(getBtnTrain(), null);
			jPanel.add(getJButton(), null);
		}
		return jPanel;
	}
	
	private Thread threadTrain = null;
	private JProgressBar jProgressBar = null;
	private class ThreadTrain extends Thread {

	    public void run() 
	    {
	    	try
	    	{
		    	threadBusy = true;	
		    	jProgressBar.setIndeterminate(true);
		    	AbstractDataModel dm = (AbstractDataModel)cmbDataModel.getSelectedItem();
				if (dm == null) {
					JOptionPane.showMessageDialog(me, "No data model selected.", "Error", JOptionPane.ERROR_MESSAGE);
					return;
				}
				classifier.train(dm, me);
				jProgressBar.setIndeterminate(false);
				threadBusy = false;
			} catch (OutOfMemoryError e) 
			{
				jProgressBar.setIndeterminate(false);
				threadBusy = false;
				JOptionPane.showMessageDialog(me, "There is not enough memory for " +
						"the training!", "Out of Memory", JOptionPane.ERROR_MESSAGE);
			}
	    }

	}
	/**
	 * This method initializes jProgressBar	
	 * 	
	 * @return javax.swing.JProgressBar	
	 */
	private JProgressBar getJProgressBar() {
		if (jProgressBar == null) {
			jProgressBar = new JProgressBar();
		}
		return jProgressBar;
	}

}  //  @jve:decl-index=0:visual-constraint="10,10"

